import { Body, Controller, Post, Get, Query, Res } from '@nestjs/common';
import type { Response } from 'express';
import * as qrcode from 'qrcode';
import { v4 as uuidV4 } from 'uuid';
import { UserService } from './user.service';
import { CreateUserDto } from './dto/create-user.dto';
import { UserResponseDto } from './dto/user-response.dto';
import { LoginUserDto } from './dto/login-user.dto';
import { SocketGateway } from '../../shared/socket.gateway';

@Controller('user')
export class UserController {
  // 用一个Map在内存中临时存储扫码状态（生产环境建议用Redis）
  private scanStatusMap = new Map<string, { status: string; userInfo?: unknown }>();
  constructor(
    private readonly userService: UserService,
    private authGateway: SocketGateway,
  ) {}

  // 注册
  @Post('register')
  async register(@Body() createUserDto: CreateUserDto) {
    const user = await this.userService.register(createUserDto);
    return new UserResponseDto(2000, '注册成功', user);
  }
  // 登录
  @Post('login')
  async login(@Body() loginUserDto: LoginUserDto) {
    const { user, access_token } = await this.userService.login(loginUserDto);
    // 密码不返回
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    const { password, ...userWithoutPassword } = user;
    return new UserResponseDto(2000, '登录成功', {
      ...userWithoutPassword,
      access_token,
    });
  }
  // 1. 生成二维码接口
  @Get('wechat/qrcode')
  async getQRCode() {
    const sceneStr = uuidV4(); // 生成唯一场景值
    // 生成微信授权URL。注意：这里使用测试号的AppID和授权回调域名
    const authUrl = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${process.env.WECHAT_APPID}&redirect_uri=${encodeURIComponent(process.env.WECHAT_CALLBACK_URL ?? 'http://127.0.0.1:80/user/wechat/callback')}&response_type=code&scope=snsapi_userinfo&state=${sceneStr}#wechat_redirect`;

    try {
      // 将授权URL生成二维码图片
      const qrCodeImage = await qrcode.toDataURL(authUrl);
      // 初始化该场景值的状态为'waiting'
      this.scanStatusMap.set(sceneStr, { status: 'waiting' });

      return new UserResponseDto(2000, '二维码生成成功', {
        qrCode: qrCodeImage,
        sceneStr: sceneStr,
      });
    } catch (error) {
      console.error('生成二维码失败', error);
      return new UserResponseDto(5000, '生成二维码失败', null);
    }
  }
  // 2. 前端轮询状态接口
  @Get('wechat/status')
  async checkStatus(@Query('sceneStr') sceneStr: string) {
    const statusInfo = this.scanStatusMap.get(sceneStr) ?? { status: 'invalid' };
    return new UserResponseDto(2000, '扫码状态查询成功', statusInfo);
  }
  // 3. 微信回调接口 (配置在测试号的“授权回调域名”下的URL)
  @Get('wechat/callback')
  async wechatCallback(@Query('code') code: string, @Query('state') sceneStr: string, @Res() res: Response) {
    try {
      // 用code换取用户信息和token
      const { user, access_token } = await this.userService.exchangeCodeForUserInfo(code);
      console.log('微信回调处理成功:', user);

      const statusInfo = {
        status: 'confirmed',
        userInfo: { ...user, access_token },
      };
      // 更新扫码状态为'confirmed'，并存储用户信息
      this.scanStatusMap.set(sceneStr, statusInfo);

      //socket方式通知前端
      this.authGateway.notifyStatusUpdate(sceneStr, statusInfo);

      // 重定向到前端页面，告知成功。也可以直接返回JSON，这里重定向更友好
      // res.redirect(`${process.env.FRONTEND_URL}?sceneStr=${sceneStr}`);
      res.json({ status: 'success', message: '扫码成功' });
    } catch (error) {
      console.error('微信回调处理失败:', error);
      res.redirect(`${process.env.FRONTEND_URL}/login`);
    }
  }
}
